package com.nulstudio.cloud.account.service;

import com.nulstudio.cloud.account.entity.NulInvite;
import com.nulstudio.cloud.common.entity.NulRole;
import com.nulstudio.cloud.account.mapper.AuthorityMapper;
import com.nulstudio.cloud.account.mapper.InviteMapper;
import com.nulstudio.cloud.common.exception.NulException;
import com.nulstudio.cloud.common.exception.NulExceptionConstants;
import jakarta.annotation.Resource;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public final class InviteService {

    private static final long INVITE_DEFAULT_EXPIRE_TIME = 7 * 24 * 3600 * 1000;

    @Resource @NonNull
    private InviteMapper inviteMapper;

    @Resource @NonNull
    private AuthorityMapper authorityMapper;

    @NonNull
    public NulInvite getInvite(@NonNull String code) throws NulException {
        final NulInvite invite = inviteMapper.getInviteByCode(code);
        if (invite == null) {
            throw new NulException(NulExceptionConstants.INVALID_INVITE_CODE);
        }
        return invite;
    }

    @NonNull
    public void checkInviteRole(@NonNull NulInvite invite) throws NulException {
        final NulRole role = authorityMapper.getRoleById(invite.getRoleId());
        NulRole.assertValidity(role);
    }

    public void registerInvite(@NonNull NulInvite invite) throws NulException {
        NulInvite.assertValidity(invite);
        inviteMapper.useInvite(invite.getCode());
    }

    @NonNull
    public NulInvite generateInvite(@NonNull Date expireTime, @NonNull String role, int remaining, boolean blocked)
        throws NulException {
        if (expireTime.before(new Date()))
            throw new NulException(NulExceptionConstants.INVALID_EXPIRE_DATE);
        final NulRole nulRole = authorityMapper.getRoleByName(role);
        NulRole.assertValidity(nulRole);
        return generateInvite(expireTime, nulRole.getId(), remaining, blocked);
    }

    @NonNull
    public NulInvite generateInvite(@NonNull Date expireTime, int roleId, int remaining, boolean blocked)
            throws NulException {
        String code;
        do {
            code = NulInvite.generate();
        } while (inviteMapper.exist(code));
        final NulInvite invite = new NulInvite(code, expireTime, roleId, remaining, blocked);
        inviteMapper.insertInvite(invite);
        return invite;
    }
}
